package top.lshaci.learning.activiti.day1;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.ProcessDefinition;
import org.junit.Test;

import java.io.InputStream;
import java.util.List;

import static top.lshaci.learning.activiti.util.ProcessEngineSingleton.singleton;

/**
 * ProcessDefinitionTest
 * 流程规则管理
 *
 * @author lshaci
 * @since 1.0.0
 */
public class ProcessDefinitionTest {
    /**
     * 1、部署流程规则
     * 一次成功的部署，会修改数据库的3张表
     * act_ge_bytearray : 2个（上传文件信息）
     * act_re_deployment: 1个（一次发布的信息）
     * act_re_procdef   : 1个（这次发布，对应的流程定义【规则】）
     */
    @Test
    public void deployProcess() {
        singleton.repositoryService()
                // 创建发布配置对象（DeploymentBuilder）
                .createDeployment()
                // 部署显示的别名
                .name("请假流程2V1")
                // 流程规则文件（必须包含）
                .addClasspathResource("LeaveFlow2.bpmn")
                // 流程规则图片
                .addClasspathResource("LeaveFlow2.png")
                .deploy();
    }

    /**
     * 2、查看流程定义
     * 流程定义的4大属性：
     * 1、id       : {key}:{version}:{sequence}
     * 2、name     : 规则文件中process节点的name属性
     * 3、key      : 规则文件中process节点的id属性
     * 4、version  : 默认从1开始，如果key存在，则在当前最高版本上自动递增（+1）。
     */
    @Test
    public void queryProcessDefinition() {
        List<ProcessDefinition> processDefinitions = singleton.repositoryService()
                .createProcessDefinitionQuery()
                .processDefinitionName("请假流程")
                .list();
        processDefinitions.forEach(pd -> {
            System.err.println(
                    StrUtil.format("id: {}, name: {}, key: {}, version: {}",
                            pd.getId(), pd.getName(), pd.getKey(), pd.getVersion())
            );
        });
    }

    /**
     * 3、删除流程定义
     */
    @Test
    public void deleteProcessDefinition() {
        RepositoryService repositoryService = singleton.repositoryService();
        // 普通删除，只能删除没有任何引用的规则
        repositoryService.deleteDeployment("1");
        // 级联删除，可以删除规则下产生的所有信息，包括历史。相对暴力，最好只提供给管理员使用
        repositoryService.deleteDeployment("1", true);
    }

    /**
     * 4、查看规则图片
     */
    @Test
    public void viewProcessResource() {
        String sub = ProcessDefinitionTest.class.getResource("/").getPath().substring(1);
        String projectPath = StrUtil.subBefore(sub, "target", true);
        RepositoryService repositoryService = singleton.repositoryService();
        String deploymentId = "5001";
        List<String> resourceNames = repositoryService
                .getDeploymentResourceNames(deploymentId);
        for (String resourceName : resourceNames) {
            System.err.println(resourceName);
            InputStream inputStream = repositoryService
                    .getResourceAsStream(deploymentId, resourceName);
            FileUtil.writeFromStream(inputStream, projectPath + "/resources/" + resourceName);
        }

    }
}
